import { useEffect, useRef } from 'react';
import { debounce } from '@/utils';

const LIST_ITEM_HEIGHT = 37;

export default function DropdownList({ field, selectedValue, list, handleSelect }) {
  const listRef = useRef();

  const listItemGroup = list.map((item, index) => {
    const selected = selectedValue === item[field.value];
    return (
      <div
        className={`h-cascader-list-item ${selected ? 'is-selected' : ''} ${
          item[field.disabled] ? 'h-disabled' : ''
        }`}
        key={index}
        onClick={() => emitValue(index)}
      >
        <span className="h-cascader-list-item__label">
          {item[field.label] || item[field.value]}
        </span>
      </div>
    );
  });

  const emitValue = index => {
    const item = list[index];
    if (item[field.disabled]) return;
    if (item[field.value] === selectedValue) {
      handleSelect(null);
    } else {
      handleSelect(list[index]);
      listRef.current.scrollTo({
        top: LIST_ITEM_HEIGHT * index,
        behavior: 'smooth',
      });
    }
  };

  useEffect(() => {
    let listRefValue = null;
    const debounceMoveFn = debounce(moveFn);
    if (listRef.current) {
      listRefValue = listRef.current;
      listRefValue.addEventListener('mousewheel', debounceMoveFn);
      const selectIndex = list.findIndex(item => selectedValue === item[field.value]);
      if (selectIndex !== -1) {
        listRefValue.scrollTop = LIST_ITEM_HEIGHT * selectIndex;
      }
    }

    function getDirection(e) {
      return e.wheelDelta ? e.wheelDelta < 0 : e.detail > 0;
    }

    function moveFn(e) {
      const indexDecimal = listRef.current.scrollTop / LIST_ITEM_HEIGHT;
      const index = getDirection(e) ? Math.ceil(indexDecimal) : Math.floor(indexDecimal);
      const item = list[index];
      listRef.current.scrollTo({
        top: LIST_ITEM_HEIGHT * index,
        behavior: 'smooth',
      });
      if (item[field.disabled]) return;
      handleSelect(list[index]);
    }

    return () => {
      listRefValue && listRefValue.removeEventListener('mousewheel', debounceMoveFn);
    };
  }, [listRef, handleSelect, list, field]);

  return (
    <div className="h-cascader-list list-1" ref={listRef}>
      {listItemGroup}
    </div>
  );
}
